package com.vhall.component.service.chat.util;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vhall.component.dao.chat.QuickRepliesMapper;
import com.vhall.component.entity.account.vo.AccountDTO;
import com.vhall.component.entity.chat.dto.QuickRepliesDTO;
import com.vhall.component.entity.chat.entity.QuickRepliesEntity;
import com.vhall.component.entity.chat.enums.QuickRepliesStatusEnum;
import com.vhall.component.entity.page.vo.PageVO;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.constant.RedisKey;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.utils.JsonUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * QuickRepliesUtils-快捷回复抽取出的部分公共接接口
 *
 * @author xing.wang
 * @date 2022/9/15
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class QuickRepliesUtils {
    private final RedisTemplate<String, String> redisTemplate;
    private final QuickRepliesMapper quickRepliesMapper;

    /**
     * 最大启用限制数量
     */
    @Value("${project.limit.quick-replies.open-num:10}")
    private Integer OPEN_COUNT_LIMIT;

    /**
     * 根据执行条件获取到快捷回复的分页结果
     *
     * @param where     搜索条件
     * @param pageIndex 页码编号
     * @param pageSize  单页显示数量
     * @return PageVO<QuickRepliesDTO> 分页集合
     */
    public PageVO<QuickRepliesDTO> getQuickRepliesDTOPageVO(LambdaQueryWrapper<QuickRepliesEntity> where, Integer pageIndex, Integer pageSize) {
        Page<QuickRepliesEntity> page = new Page<>(pageIndex, pageSize);
        Page<QuickRepliesEntity> quickRepliesEntityPage = quickRepliesMapper.selectPage(page, where);
        List<QuickRepliesDTO> list = new ArrayList<>();
        if (Objects.nonNull(quickRepliesEntityPage) && quickRepliesEntityPage.getTotal() > 0) {
            list = quickRepliesEntityPage.getRecords().stream().map(quickRepliesEntity -> {
                QuickRepliesDTO quickRepliesDTO = new QuickRepliesDTO();
                BeanUtil.copyProperties(quickRepliesEntity, quickRepliesDTO, false);
                return quickRepliesDTO;
            }).collect(Collectors.toList());
        }
        return new PageVO<>(pageIndex, pageSize, (int) page.getTotal(), list);
    }

    /**
     * 判断当前的快捷回复是否存在
     *
     * @param content   回复内容
     * @param repliesId 快捷回复id[新建的时候传递0]
     * @return 存在时返回true, 不存在返回false
     */
    public Boolean checkContentExists(String content, Integer repliesId) {
        LambdaQueryWrapper<QuickRepliesEntity> where = Wrappers.lambdaQuery();
        where.eq(QuickRepliesEntity::getContent, content);
        where.ne(QuickRepliesEntity::getId, repliesId);
        Integer count = quickRepliesMapper.selectCount(where);
        return Objects.nonNull(count) && count >= 1;
    }

    /**
     * 判断是否正常能获取到登录信息
     *
     * @param token 登录token
     */
    public void checkToken(String token) {
        String tokenData = redisTemplate.opsForValue().get(RedisKey.AUTH_TOKEN + token);
        log.info("tokenData:{}", tokenData);
        if (!StringUtils.isNotEmpty(tokenData)) {
            throw new BusinessException(BizErrorCode.AUTH_LOGIN_TOKEN_INVALID);
        }
    }

    /**
     * 检查当前用户下开启的快捷回复数量是否超过限定值
     *
     * @param accountId 用户id
     */
    public void checkQuickRepliesOpenNum(Integer accountId) {
        LambdaQueryWrapper<QuickRepliesEntity> where = Wrappers.lambdaQuery();
        where.eq(QuickRepliesEntity::getStatus, QuickRepliesStatusEnum.OPEN.getStatus());
//        where.eq(QuickRepliesEntity::getAccountId, accountId);
        int openNum = quickRepliesMapper.selectCount(where);
        log.info("START_US_COUNT_LIMIT:{}", OPEN_COUNT_LIMIT);
        if (openNum >= OPEN_COUNT_LIMIT) {
            throw new BusinessException(BizErrorCode.COMP_QUICKREPLIES_COUNT_OVERFLOW_ERROR);
        }
    }

    /**
     * 从token中获取用户id
     *
     * @param token 登录token
     * @return 用户id
     */
    public Integer getAccountIdFromToken(String token) {
        String tokenData = redisTemplate.opsForValue().get(RedisKey.AUTH_TOKEN + token);
        log.info("tokenData:{}", tokenData);
        if (!StringUtils.isNotEmpty(tokenData)) {
            throw new BusinessException(BizErrorCode.AUTH_LOGIN_TOKEN_INVALID);
        }
        tokenData = (String) JSON.parse(tokenData);
        AccountDTO existToken = JsonUtil.objectFromJSONString(tokenData, AccountDTO.class);
        Integer accountId = existToken.getAccountId();
        log.info("accountId:{}", accountId);
        return accountId;
    }
}
